package com.kang.service.warMap.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.kang.CommonsUtils;
import com.kang.MsgResult;
import com.kang.bean.bot.FoodStore;
import com.kang.bean.bot.MapType;
import com.kang.bean.bot.WarMap;
import com.kang.dto.QueryDto;
import com.kang.dto.WarMapDto;
import com.kang.mapper.FoodStoreMapper;
import com.kang.mapper.MapTypeMapper;
import com.kang.mapper.WarMapMapper;
import com.kang.service.warMap.MapTypeService;
import com.kang.service.warMap.WarMapService;
import com.kang.vo.WarMapVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @program: service
 * @description:
 * @author: K.faWu
 * @create: 2022-05-09 17:54
 **/
@Service
public class WarMapServiceImpl extends ServiceImpl<WarMapMapper, WarMap> implements WarMapService {
    @Autowired
    private WarMapMapper warMapMapper;
    @Autowired
    private MapTypeMapper mapTypeMapper;
    @Autowired
    private FoodStoreMapper foodStoreMapper;
    @Autowired
    private MapTypeService mapTypeService;

    @Override
    public List<WarMapVo> create(WarMapDto warMapDto) {
        List<WarMapVo> list = new ArrayList<>();
        List<MapType> typeList = mapTypeMapper.selectList(new QueryWrapper<>());

        Integer xs = warMapDto.getXs();
        Integer ys = warMapDto.getYs();
        for (int y = 0; y < ys; y++) {
            for (int x = 0; x < xs; x++) {
                WarMapVo warMapVo = new WarMapVo();
                warMapVo.setX(x);
                warMapVo.setY(y);
                WarMap.initWarMap(warMapVo);
                warMapVo.setSoldierNum((int) (Math.random() * 40));
                warMapVo.setFarmerNum((int) (Math.random() * 40));
                double v = Math.random() * 100;
                for (MapType mapType : typeList) {
                    //根据每个模块出现的几率进行划分
                    if (v < mapType.getWeight()) {
                        warMapVo.setMapType(mapType);
                        break;
                    }
                }
                list.add(warMapVo);
            }
        }
        return list;
    }

    @Override
    public void add(WarMapDto warMapDto) {
        String name = warMapDto.getName();
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
        String code = format.format(new Date());
        List<WarMapVo> list = warMapDto.getList();
        for (WarMapVo warMap : list) {
            warMap.setName(name);
            warMap.setCode(code);
            warMap.setType(warMap.getMapType().getTypeCode());
            warMapMapper.insert(warMap);
        }
    }

    @Override
    public void add(WarMapDto warMapDto, String groupCode) {
        String name = warMapDto.getName();
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
        String code = format.format(new Date());
        List<WarMapVo> list = warMapDto.getList();
        List<WarMap> warMapList = new ArrayList<>();
        for (WarMapVo warMap : list) {
            warMap.setName(name);
            warMap.setCode(code);
            warMap.setType(warMap.getMapType().getTypeCode());
            warMap.setGroupCode(groupCode);
            warMapList.add(warMap);
        }
        saveBatch(warMapList);
    }

    @Override
    public PageInfo<WarMap> getList(List<QueryDto> queryDtos, Pageable page) {
        QueryWrapper<WarMap> warMapQueryWrapper = new QueryWrapper<>();
        warMapQueryWrapper.groupBy("code", "group_code", "name");
        warMapQueryWrapper.select("name", "code", "group_code");
        String name, groupCode;
        if (queryDtos != null && queryDtos.size() != 0) {
            for (QueryDto queryDto : queryDtos) {
                if ("name".equals(queryDto.getField())) {
                    name = queryDto.getValue();
                    warMapQueryWrapper.eq("name", name);
                } else if ("groupCode".equals(queryDto.getField())) {
                    groupCode = queryDto.getValue();
                    warMapQueryWrapper.eq("group_code", groupCode);
                }
            }
        }
        PageHelper.startPage(page.getPageNumber(), page.getPageSize());
        List<WarMap> list = warMapMapper.selectList(warMapQueryWrapper);
        return new PageInfo<>(list);
    }

    /**
     * 获取该玩家城池附近地图
     */
    @Override
    public List<WarMap> explore(String accountCode, String groupCode) {
        QueryWrapper<WarMap> queryWrapper = CommonsUtils.selectCode(accountCode, groupCode);
        List<WarMap> list = warMapMapper.selectList(queryWrapper);
        Set<WarMap> warMapSet = new HashSet<>();
        for (WarMap warMap : list) {
            Integer x = warMap.getX();
            Integer y = warMap.getY();
            for (int i = x - 1; i <= x + 1; i++) {
                for (int j = y - 1; j <= y + 1; j++) {
                    QueryWrapper<WarMap> warMapQueryWrapper = new QueryWrapper<>();
                    warMapQueryWrapper.eq("code", warMap.getCode());
                    warMapQueryWrapper.eq("x", i);
                    warMapQueryWrapper.eq("y", j);
                    WarMap warMap1 = warMapMapper.selectOne(warMapQueryWrapper);
                    if (warMap1 != null) {
                        warMapSet.add(warMap1);
                    }
                }
            }
        }
        list.forEach(warMapSet::remove);

        return new ArrayList<>(warMapSet);
    }

    @Override
    public List<WarMap> initWarMap(String groupCode) {
        QueryWrapper<WarMap> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("group_code", groupCode);
        long count = warMapMapper.selectCount(queryWrapper);
        List<WarMap> list;
        if (count == 0) {
            //如果没有地图则创建一个地图
            WarMapDto warMapDto = new WarMapDto();
            warMapDto.setXs(10);
            warMapDto.setYs(10);
            List<WarMapVo> mapVoList = this.create(warMapDto);
            warMapDto.setList(mapVoList);
            this.add(warMapDto, groupCode);

        }
        queryWrapper.isNull("account_code");
        list = warMapMapper.selectList(queryWrapper);
        return list;
    }

    /**
     * 获取指定区域周围指定人员的地盘
     */
    @Override
    public List<WarMap> exploreByWarId(String code, String groupCode, WarMap warMap) {
        Set<WarMap> warMapSet = new HashSet<>();
        Integer x = warMap.getX();
        Integer y = warMap.getY();
        for (int i = x - 1; i <= x + 1; i++) {
            for (int j = y - 1; j <= y + 1; j++) {
                QueryWrapper<WarMap> warMapQueryWrapper = new QueryWrapper<>();
                warMapQueryWrapper.eq("code", warMap.getCode());
                warMapQueryWrapper.eq("x", i);
                warMapQueryWrapper.eq("y", j);
                warMapQueryWrapper.eq("account_code", code);
                warMapQueryWrapper.eq("group_code", groupCode);
                WarMap warMap1 = warMapMapper.selectOne(warMapQueryWrapper);
                if (warMap1 != null) {
                    warMapSet.add(warMap1);
                }
            }
        }
        return new ArrayList<>(warMapSet);
    }


    @Override
    public String addPro(String accountCode, String groupCode, Integer proNum, String accountNickname, WarMap warMap) {
        Integer proMax = warMap.getProMax();
        Integer max = warMap.getMax();
        Integer sum = warMap.getSum();
        Integer farmerNum = warMap.getFarmerNum();
        QueryWrapper<FoodStore> queryWrapper = CommonsUtils.selectCode(accountCode, groupCode);
        FoodStore foodStore = foodStoreMapper.selectOne(queryWrapper);
        if (foodStore != null) {
            //招募的平民数量加上已有的平民不能多于平民上限，加上现在这座城池的总人数不能多于总人口上线
            if (proMax >= farmerNum + proNum && max >= sum + proNum) {
                //食物数量
                Long foodNum = foodStore.getNum();
                long newFoodNum = foodNum - (proNum * 2);
                if (newFoodNum >= 0) {
                    //有足够的食物创造人口
                    warMap.setFarmerNum(warMap.getFarmerNum() + proNum);
                    warMapMapper.updateById(warMap);
                    //扣除食物
                    foodStore.setNum(newFoodNum);
                    foodStoreMapper.updateById(foodStore);
                    return MsgResult.addProSuccess(accountNickname, warMap, foodStore, foodNum - newFoodNum);
                } else {
                    return "粮食不足！";
                }
            } else {
                String result = "";
                if (proMax >= farmerNum + proNum) {
                    result = "增加数量超过当前城池所能容纳的平民上限！";
                } else {
                    result  = "增加数量超过当前城池所能容纳的人口上限！";
                }
                return result;
            }
        }
        return MsgResult.NOT_CITY;
    }

    @Override
    public WarMapDto getByCodeAndGroup(WarMapDto warMapDto) {
        QueryWrapper<WarMap> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("code", warMapDto.getCode());
        List<WarMap> list = warMapMapper.selectList(queryWrapper);
        Map<String, MapType> mapAll = mapTypeService.getMapAll();
        Integer xs = 0;
        Integer ys = 0;
        List<WarMapVo> warMapVos = new ArrayList<>();
        for (WarMap warMap : list) {
            WarMapVo warMapVo = new WarMapVo();
            BeanUtils.copyProperties(warMap, warMapVo);
            MapType mapType = mapAll.get(warMap.getType());
            warMapVo.setMapType(mapType);
            warMapVos.add(warMapVo);
            //获取纵横最大数
            if (warMap.getX() > xs) {
                xs = warMap.getX();
            }
            if (warMap.getY() > ys) {
                ys = warMap.getY();
            }
        }
        warMapDto.setX(xs);
        warMapDto.setY(ys);
        warMapDto.setList(warMapVos);
        return warMapDto;
    }
}
